#ifndef H_KOMPR_JNI
#define H_KOMPR_JNI

#include <libavutil/audioconvert.h>

static JavaMethod empty_constructor = {"<init>", "()V"};

// InterruptedException
static char *interrupted_exception_class_path_name = "java/lang/InterruptedException";

// RuntimeException
static char *runtime_exception_class_path_name = "java/lang/RuntimeException";

// NotPlayingException
//static char *not_playing_exception_class_path_name = "com/appunite/ffmpeg/NotPlayingException";

// Object
static char *object_class_path_name = "java/lang/Object";

// HashMap
static char *hash_map_class_path_name = "java/util/HashMap";
static char *map_class_path_name = "java/util/Map";
static JavaMethod map_key_set = {"keySet", "()Ljava/util/Set;"};
static JavaMethod map_get = {"get", "(Ljava/lang/Object;)Ljava/lang/Object;"};
static JavaMethod map_put = {"put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"};

// FFmpegStreamInfo.CodeType
enum CodecType {
	CODEC_TYPE_UNKNOWN = 0,
	CODEC_TYPE_AUDIO = 1,
	CODEC_TYPE_VIDEO = 2,
	CODEC_TYPE_SUBTITLE = 3,
	CODEC_TYPE_ATTACHMENT = 4,
	CODEC_TYPE_NB = 5,
	CODEC_TYPE_DATA = 6
};

enum StreamNumber {
	NO_STREAM = -2,
	UNKNOWN_STREAM = -1,
};

// FFmpegStreamInfo
static char *stream_info_class_path_name = "com/avzipper/FFmpegStreamInfo";
static JavaMethod steram_info_set_metadata = {"setMetadata", "(Ljava/util/Map;)V"};
static JavaMethod steram_info_set_media_type_internal = {"setMediaTypeInternal", "(I)V"};
static JavaMethod stream_info_set_stream_number = {"setStreamNumber", "(I)V"};


// Set
static char *set_class_path_name = "java/util/Set";
static JavaMethod set_iterator = {"iterator", "()Ljava/util/Iterator;"};

// Iterator
static char *iterator_class_path_name = "java/util/Iterator";
static JavaMethod iterator_next = {"next", "()Ljava/lang/Object;"};
static JavaMethod iterator_has_next = {"hasNext", "()Z"};

static const struct {
    const char *name;
    int         nb_channels;
    uint64_t     layout;
} channel_android_layout_map[] = {
    { "mono",        1,  AV_CH_LAYOUT_MONO },
    { "stereo",      2,  AV_CH_LAYOUT_STEREO },
    { "2.1",         3,  AV_CH_LAYOUT_2POINT1 },
    { "4.0",         4,  AV_CH_LAYOUT_4POINT0 },
    { "4.1",         5,  AV_CH_LAYOUT_4POINT1 },
    { "5.1",         6,  AV_CH_LAYOUT_5POINT1_BACK },
    { "6.0",         6,  AV_CH_LAYOUT_6POINT0 },
    { "7.0(front)",  7,  AV_CH_LAYOUT_7POINT0_FRONT },
    { "7.1",         8,  AV_CH_LAYOUT_7POINT1 },
};


//Compressor
static char *Kompressor_class_path_name = "com/avzipper/Compressor";
static JavaField native_compressor = {"nativeCompressor", "I"};
static JavaMethod compressor_set_stream_info = {"setStreamsInfo", "([Lcom/avzipper/FFmpegStreamInfo;)V"};
static JavaMethod signal_handler = {"handleSignalFromNative", "(I)V"};

int jni_init(JNIEnv *env, jobject thiz);
void jni_dealloc(JNIEnv *env, jobject thiz);

int jni_set_data_source(JNIEnv *env, jobject thiz, jstring string, jstring outfile,
		jobject dictionary, int video_stream_no, int audio_stream_no,
		int subtitle_stream_no);

int jni_encode(JNIEnv *, jobject , jstring);

int jni_get_video_duration(JNIEnv *env, jobject thiz);

void jnit_compressor_test(JNIEnv *env, jobject thiz, int stream_no);

static JNINativeMethod compressor_methods[] = {

	{"initNative", "()I", (void*) jni_init},
	{"setDataSourceNative", "(Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;III)I", (void*) jni_set_data_source},
	{"encodeVideo", "(Ljava/lang/String;)I", (void*) jni_encode},
	{"getVideoDurationNative", "()I", (void*) jni_get_video_duration},
	{"deallocNative", "()V", (void*)jni_dealloc},
	{"testEncode", "(I)V", (void*)jnit_compressor_test},
};

#endif
